import { CLIENT_HEIGHT, CLIENT_WIDTH } from "./util";

// 事件控制class
export const GUIDE_EVENT_ENABLE = "guide-event-enable";
export const GUIDE_EVENT_DISABLE = "guide-event-disable";

/** 创建元素 */
function newEl(tag: string, attrs?: Record<string, string>): HTMLElement {
  const el = document.createElement(tag);
  attrs &&
    Object.keys(attrs).forEach((key) => {
      el.setAttribute(key, attrs[key]);
    });
  return el;
}

/** 创建guide所有元素 */
export function createGuideEls() {
  const wrap = newEl("div", { class: "guide-wrap", "guide-tooltip": "" });
  const block = newEl("div", { class: "guide-block" });
  const tooltip = newEl("div", { class: "guide-tooltip" });
  const tip = newEl("div", { class: "guide-tooltip-tip" });
  const arrow = newEl("div", { class: "guide-tooltip-arrow" });
  const btns = newEl("div", { class: "guide-tooltip-btns" });
  const skip = newEl("button", { class: "guide-btn guide-btn-skip" });
  const prev = newEl("button", { class: "guide-btn guide-btn-prev" });
  const next = newEl("button", { class: "guide-btn guide-btn-next" });
  const complete = newEl("button", { class: "guide-btn guide-btn-complete" });
  wrap.appendChild(block);
  block.appendChild(tooltip);
  tooltip.appendChild(tip);
  tooltip.appendChild(arrow);
  tooltip.appendChild(btns);
  btns.appendChild(skip);
  btns.appendChild(prev);
  btns.appendChild(next);
  btns.appendChild(complete);
  return { wrap, block, tooltip, tip, arrow, btns, skip, prev, next, complete };
}

/** 获取提示框的位置 */
export function getTooltipPosition(el, mainPosition?: string) {
  const { width, height, left, top } = el.getBoundingClientRect();
  //通过对目标所在位置分析  计算出提示框需要展示的位置
  let l = left;
  let r = CLIENT_WIDTH - (left + width);
  let t = top;
  let b = CLIENT_HEIGHT - (top + height);
  let hMax = Math.max(l, r); //横向空间最大的方向
  let vMax = Math.max(t, b); //纵向空间最大的方向
  let max = Math.max(hMax, vMax); //所有空间最大的方向
  let arrowPosition; //次方向 决定提示框对齐的方向
  // horizontal / vertical
  if (!mainPosition) {
    if (vMax < CLIENT_HEIGHT / 2 && max === hMax) {
      mainPosition = hMax === l ? "left" : "right";
    } else {
      mainPosition = vMax === t ? "top" : "bottom";
    }
  }
  if (["left", "right"].includes(mainPosition)) {
    arrowPosition =
      height > CLIENT_HEIGHT / 2
        ? "arrow-y-center"
        : vMax === b
        ? "arrow-bottom"
        : "arrow-top";
  } else {
    arrowPosition =
      width > CLIENT_WIDTH / 2
        ? "arrow-x-center"
        : hMax === r
        ? "arrow-left"
        : "arrow-right";
  }
  return { mainPosition, arrowPosition };
}
/** 提示框间距 */
const SPACE_LENGTH = 10;
/** 获取提示框的样式 */
export function getTipStyle(el: HTMLElement, position?: string) {
  const { mainPosition, arrowPosition } = getTooltipPosition(el, position);
  const { width, height } = el.getBoundingClientRect();
  let style: any = {
    left: "initial",
    top: "initial",
    bottom: "initial",
    right: "initial",
    transform: "none",
  };
  if (mainPosition === "bottom") {
    style.top = height + SPACE_LENGTH + "px";
  } else if (mainPosition === "top") {
    style.bottom = height + SPACE_LENGTH + "px";
  } else if (mainPosition === "left") {
    style.right = width + SPACE_LENGTH + "px";
  } else if (mainPosition === "right") {
    style.left = width + SPACE_LENGTH + "px";
  }
  if (arrowPosition === "arrow-y-center") {
    style.top = "50%";
    style.transform = "translateY(-50%)";
  } else if (arrowPosition === "arrow-x-center") {
    style.left = "50%";
    style.transform = "translateX(-50%)";
  } else if (arrowPosition === "arrow-bottom") {
    style.bottom = 0;
  } else if (arrowPosition === "arrow-top") {
    style.top = 0;
  } else if (arrowPosition === "arrow-left") {
    style.left = 0;
  } else if (arrowPosition === "arrow-right") {
    style.right = 0;
  }
  return { mainPosition, arrowPosition, style };
}

export function addCls(el: HTMLElement, cls: string) {
  el.classList.add(cls);
  el.setAttribute(cls, "");
}
export function removeCls(el: HTMLElement, cls: string) {
  el.classList.remove(cls);
  el.removeAttribute(cls);
}
export function hasCls(el: HTMLElement, cls: string) {
  return el.classList.contains(cls) || el.getAttribute(cls) === "";
}
export function setCls(el: HTMLElement, cls: string) {
  el.className = cls;
}

export function setStyle(el: HTMLElement, style: Record<string, any>) {
  let cssText = "";
  Object.keys(style).forEach((key) => {
    cssText += `${key}: ${style[key]};`;
  });
  el.style.cssText = cssText;
}

export function showEl(el: HTMLElement, display: boolean) {
  display ? removeCls(el, "guide-hide") : addCls(el, "guide-hide");
}
